#include <iostream>
#include <string>

class Person {
public:
    // 委托构造函数：当只提供一个参数（名称）时，委托构造函数被调用，它委托给主构造函数并使用默认年龄。
    Person(const std::string& name) : Person(name, 30) {
        std::cout << "Delegate constructor called." << std::endl;
    }

    // 主构造函数：接受名称和年龄，完成对象的完全初始化。
    Person(const std::string& name, int age) : name(name), age(age) {
        std::cout << "Main constructor called." << std::endl;
    }

    // 转换构造函数：允许从C风格字符串直接构造Person对象，调用委托构造函数进行进一步初始化。
    Person(const char* name) : Person(std::string(name)) {
        std::cout << "Conversion constructor called." << std::endl;
    }

    // 拷贝构造函数：用于创建一个新的Person对象作为现有对象的副本。
    Person(const Person& other) : name(other.name), age(other.age) {
        std::cout << "Copy constructor called." << std::endl;
    }

    // 移动构造函数：将资源从另一个Person对象（临时对象）移动到新对象中，通常用于优化性能。
    Person(Person&& other) noexcept : name(std::move(other.name)), age(other.age) {
        other.age = 0;  // 清除源对象的年龄信息，确保源对象处于合适的状态。
        std::cout << "Move constructor called." << std::endl;
    }

    // 成员函数用于显示Person的当前状态。
    void display() const {
        std::cout << "Name: " << name << ", Age: " << age << std::endl;
    }

private:
    std::string name;
    int age;
};

int main() {
    // 使用转换构造函数，从字符串直接创建Person对象。
    Person p1 = "John Doe";
    p1.display();

    // 使用委托构造函数，仅提供名字，年龄使用默认值。
    Person p2 = "Jane Doe";
    p2.display();

    // 使用拷贝构造函数，复制p1为p3。
    Person p3 = p1;
    p3.display();

    // 使用移动构造函数，将p2的资源移动到p4。
    Person p4 = std::move(p2);
    p4.display();

    return 0;
}